package database

import (
	"time"

	"gddgame.cc/galaxy/common/feature/supernova"
	"gddgame.cc/galaxy/utils/orm"
)

var (
	EnvironmentModel = orm.NewModel("database_environment", &Environment{}, nil)
	RegionModel      = orm.NewModel("database_region", &Region{}, nil)
	SnapshotModel    = orm.NewModel("database_snapshot", &Snapshot{}, nil)
	RecordModel      = orm.NewModel("database_record", &Record{}, nil)
)

type Process string

const (
	Wait    Process = "wait"
	Running         = "running"
	Success         = "success"
	Fail            = "fail"
)

type SnapshotType string

const (
	AutoSnapshotType   SnapshotType = "auto"
	ManualSnapshotType SnapshotType = "manual"
)

type TableInfo interface {
	GetTable() *supernova.Table
	GetRecord() int
}

type EnvironmentTable struct {
	Table         *supernova.Table `json:"table"`
	Name          string           `json:"name"`
	IncludeStruct bool             `json:"include_struct"`
	IncludeRecord bool             `json:"include_record"`
}

func (environmentTable *EnvironmentTable) GetTable() *supernova.Table {
	return environmentTable.Table
}

func (environmentTable *EnvironmentTable) GetRecord() int {
	return 0
}

type EnvironmentTableSlice []EnvironmentTable

func (slice EnvironmentTableSlice) Transform() []TableInfo {
	list := make([]TableInfo, len(slice))
	for index, table := range slice {
		list[index] = &table
	}
	return list
}

type SnapshotTable struct {
	Table         *supernova.Table `json:"table"`
	Name          string           `json:"name"`
	Records       int              `json:"records"`
	IncludeStruct bool             `json:"include_struct"`
	IncludeRecord bool             `json:"include_record"`
}

func (snapshotTable *SnapshotTable) GetTable() *supernova.Table {
	return snapshotTable.Table
}

func (snapshotTable *SnapshotTable) GetRecord() int {
	return snapshotTable.Records
}

type SnapshotTableSlice []SnapshotTable

func (slice SnapshotTableSlice) Transform() []TableInfo {
	list := make([]TableInfo, len(slice))
	for index, table := range slice {
		list[index] = &table
	}
	return list
}

type TableDiffInfo struct {
	Name          string   `json:"name"`
	AddColumn     []string `json:"add_column"`
	RemoveColumn  []string `json:"remove_column"`
	ChangeColumn  []string `json:"change_column"`
	AddIndex      []string `json:"add_index"`
	RemoveIndex   []string `json:"remove_index"`
	AddForeign    []string `json:"add_foreign"`
	RemoveForeign []string `json:"remove_foreign"`
	OldRecord     int      `json:"old_record"`
	NewRecord     int      `json:"new_record"`
}
type DiffInfo struct {
	New   []string                 `json:"new"`
	Old   []string                 `json:"old"`
	Table map[string]TableDiffInfo `json:"table"`
}
type RegionPreference struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}
type Region struct {
	Id         int                `json:"id" orm:"auto" sql:"INT"`
	Name       string             `json:"name" sql:"VARCHAR"`
	Prefix     string             `json:"prefix" sql:"VARCHAR"`
	Default    int                `json:"default" sql:"INT"`
	Preference []RegionPreference `json:"preference" sql:"JSON"`
}

type Environment struct {
	Id       int                   `json:"id" orm:"auto" sql:"INT"`
	RegionId int                   `json:"region_id" sql:"INT"`
	DSN      string                `json:"dsn" sql:"VARCHAR"`
	Tables   EnvironmentTableSlice `json:"tables" sql:"JSON"`
	Name     string                `json:"name" sql:"VARCHAR"`
	LastTime *time.Time            `json:"last_time"  sql:"DATETIME"`
}

type Snapshot struct {
	Id            int                `json:"id" orm:"auto" sql:"INT"`
	RegionId      int                `json:"region_id" sql:"INT"`
	EnvironmentId int                `json:"environment_id" sql:"INT"`
	CreateTime    *time.Time         `json:"create_time" orm:"createTime" sql:"DATETIME"`
	FinishTime    *time.Time         `json:"finish_time" sql:"DATETIME"`
	Tables        SnapshotTableSlice `json:"tables" sql:"JSON"`
	Result        []byte             `json:"result" sql:"MEDIUMBLOB"`
	Remark        string             `json:"remark" sql:"VARCHAR"`
	Process       Process            `json:"process" sql:"VARCHAR"`
	Type          SnapshotType       `json:"type" sql:"VARCHAR"`
}

type Record struct {
	Id            int        `json:"id" orm:"auto" sql:"INT"`
	RegionId      int        `json:"region_id" sql:"INT"`
	EnvironmentId int        `json:"environment_id" sql:"INT"`
	SnapshotId    int        `json:"snapshot_id" sql:"INT"`
	ClearRecord   bool       `json:"clear_record" sql:"TINYINT"`
	CreateTime    *time.Time `json:"create_time" orm:"createTime" sql:"DATETIME"`
	FinishTime    *time.Time `json:"finish_time" sql:"DATETIME"`
	Process       Process    `json:"process" sql:"VARCHAR"`
	Result        string     `json:"result" sql:"TEXT"`
}
